/*
The surface-physics project: http://code.google.com/p/surface-physics/
Adds real world physics based on the Bullet physics engine, to bases in the Orbiter space
flight simulation software.

Written by Abhijit Nandy
License : Apache License 2.0

Bump_Thread.h
Defines a thread interface and thread class to create and manage threads in Bump

*/


#pragma once

#include "process.h"

#include "Bump_ThreadBarrier.h"


class Bump_ThreadTargetInterface{

public:
	Bump_ThreadTargetInterface(){}
	~Bump_ThreadTargetInterface(){}

	virtual int run() = 0;

};



class Bump_Thread
{

	//thread specific stuff;
	HANDLE hThread;
	unsigned threadID;
	bool keepRunningThread;
	bool threadRunning;
	char toutput[100];

	CRITICAL_SECTION critsec;

	Bump_ThreadBarrier *threadBarrier;
	Bump_ThreadTargetInterface *threadTarget;


public:



	Bump_Thread(Bump_ThreadTargetInterface *target, Bump_ThreadBarrier *barr)
	{
		threadTarget = target;
		threadBarrier = barr;
		keepRunningThread = true;
		hThread = (HANDLE)_beginthreadex(NULL , 0, &threadEntry, this, 0, &threadID);
	};

	~Bump_Thread()
	{
		CloseHandle(hThread);
	};

	static unsigned __stdcall threadEntry(void *param)
	{
		Bump_Thread *thrd = (Bump_Thread*)param;

		oapiWriteLog("thread created");

		thrd->threadRunning = true;

		while(thrd->keepRunningThread){
			thrd->threadBarrier->wait();
			thrd->threadTarget->run();
		}


		//sprintf_s(toutput, 1000, "%s%d", endgame, thrd->threadTarget->baseID);


		thrd->threadRunning = false;

		_endthreadex(0);
		return 0;



	}

	//Will be called from another thread.
	int stop()
	{
		keepRunningThread = false;
		return 0;
	}

	//Optional, iterations to wait before forcing the thread shut
	//Will be called from another thread.
	int join(long waitCount)
	{
		while(threadRunning)
			Sleep(100);			//to yield at regular intervals
		return 0;
	}

	void setBarrier(Bump_ThreadBarrier* barr){
		threadBarrier = barr;
	}

	Bump_ThreadBarrier* getBarrier(void){
		return threadBarrier;
	}

};


